<?php

namespace Plugins\AdminBasic\Http\Admin\Service\MakeCURDFiles;

use App\Enums\Attributes\DesAttribute;
use App\Enums\Attributes\TagAttribute;
use App\Enums\EnumTraits\EnumStatusTrait;
use Hyperf\Stringable\Str;
use Sc\Util\ClassFile\Components\Attribute;
use Sc\Util\ClassFile\Components\ClassFileConstruction;
use Sc\Util\ClassFile\Components\Constant;

class MakeEnum extends AbstractMake
{
    private array $makeRes = [];

    public function make(): string
    {
        foreach ($this->fields as $field) {
            if (!$field['status_map']) {
                continue;
            }
            if (MakeEnum::fieldIsBoolean($field['status_map'])){
                continue;
            }
            $enum = new ClassFileConstruction(Str::studly($this->table . 'Enum ' . $field['field']));
            $enum->setNamespace($this->getNamespace('Enums'));
            $enum->setIsEnum(true);
            $enum->setEnumBackedType('int');
            $enum->addUses(DesAttribute::class);
            $enum->addUses(TagAttribute::class);
            $enum->addUses(EnumStatusTrait::class);
            $enum->addTraits(EnumStatusTrait::class);
            $enum->setDocBlock($this->tableComment . ': ' . $field['comment']);

            $this->makeCases($field['status_map'], $enum);

            $filename        = preg_replace('/\w+\.php$/', $enum->getName() . '.php', $this->getFilename('Enum'));
            $this->makeRes[] = "Enum {$field['field']}" . $this->makeFile($filename, $enum->out());
        }

        return "";
    }

    public function getMakeRes(): array
    {
        return $this->makeRes;
    }

    /**
     * 枚举状态主题
     *
     * @return array
     */
    private function getEnumTheme(): array
    {
        $types  = ['', 'success', 'warning', 'danger', 'info', 'primary'];
        $themes = ['light', 'dark', 'plain'];

        $res = [];
        foreach ($themes as $theme) {
            foreach ($types as $type) {
                $res[] = [$type, $theme];
            }
        }

        return $res;
    }

    /**
     * @param                       $statusMap
     * @param ClassFileConstruction $enum
     *
     * @return void
     */
    private function makeCases($statusMap, ClassFileConstruction $enum): void
    {
        $enumTheme = $this->getEnumTheme();

        foreach ($statusMap as ['key' => $value, 'value' => $comment]) {
            $enum->addConstants(function () use ($value, $comment, &$enumTheme, $enum) {
                $constant = new Constant($this->statusMapTranslationRes[$comment]);
                $constant->setIsEnum(true);
                $constant->setValue((int)$value);
                $constant->setDocBlockComment($comment);

                $constant->addAttribute(function () use ($comment, $enum) {
                    $attribute = new Attribute($enum->getAppropriateClassName(DesAttribute::class));
                    $attribute->addParam($comment);
                    return $attribute;
                });

                $constant->addAttribute(function () use (&$enumTheme, $enum) {
                    $attribute = new Attribute($enum->getAppropriateClassName(TagAttribute::class));
                    [$type, $theme] = next($enumTheme);
                    $attribute->addParam($type);
                    $attribute->addParam($theme);
                    return $attribute;
                });

                return $constant;
            });
        }
    }


    public static function fieldIsBoolean(array $fieldMapInfo): bool
    {
        return array_intersect(array_column($fieldMapInfo, 'key'), ['0', '1']) === ['0', '1']
            && array_intersect(array_column($fieldMapInfo, 'value'), ["否", "是"]) === ["否", "是"];
    }
}
